package com.java.tutorials.concurrency;

import java.util.concurrent.Semaphore;

/**
 * 通过信号量(Semaphore)实现生产者/消费者
 * @author Jun Yang
 */
class Q {
    int n = 0;
    static Semaphore semCon = new Semaphore(0);
    static Semaphore semProd = new Semaphore(1);

    void get() {
        try {
            semCon.acquire();
        } catch (InterruptedException e) {
            System.out.println("InterruptedException caught.");
        }
        System.out.printf("Got: %d\n", n);
        semProd.release();
    }

    void put(int n) {
        try {
            semProd.acquire();
        } catch (InterruptedException e) {
            System.out.println("InterruptedException caught.");
        }
        this.n = n;
        System.out.printf("Put: %d\n", n);
        semCon.release();
    }

}

class Producer implements Runnable {
    Q q;
    Producer(Q q) {
        this.q = q;
        new Thread(this,"Producer").start();
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            q.put(i);
        }
    }
}

class Consumer implements Runnable {
    Q q;
    Consumer(Q q) {
       this.q = q;
       new Thread(this,"Consumer").start();
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            q.get();
        }
    }
}

public class ProdCon {
    public static void main(String[] args) {
        Q q =  new Q();
        new Producer(q);
        new Consumer(q);
    }
}
